import 'dart:core';
import 'dart:io';
import 'package:app/model/model.dart';
import 'package:device_info_plus/device_info_plus.dart';
import 'package:intl/intl.dart';
import 'package:permission_handler/permission_handler.dart';

class TimeDifference {
  final String days;
  final String hours;
  final String minutes;
  final String seconds;

  TimeDifference({
    required this.days,
    required this.hours,
    required this.minutes,
    required this.seconds,
  });
}

class Utils {
  Utils._();
  // 一天的毫秒数
  static const int day = 86400000;
  static int normalizeTimestamp(int timestamp) {
    return timestamp.toString().length == 10 ? timestamp * 1000 : timestamp;
  }

  static String formatDate(int timestamp, String format) {
    // 处理秒级时间戳

    final date = DateTime.fromMillisecondsSinceEpoch(
      normalizeTimestamp(timestamp),
    );
    final daysOfWeek = ['星期日', '星期一', '星期二', '星期三', '星期四', '星期五', '星期六'];
    format = format.replaceAllMapped(RegExp(r'(y+)', caseSensitive: false), (
      m,
    ) {
      final year = date.year.toString();
      return year.substring(year.length - m.group(0)!.length);
    });

    // 月份补零 (M -> 1, MM -> 01)
    format = format.replaceAllMapped(RegExp(r'(M+)'), (m) {
      return date.month.toString().padLeft(m.group(0)!.length, '0');
    });

    // 日期补零 (d -> 1, dd -> 01)
    format = format.replaceAllMapped(RegExp(r'(d+)', caseSensitive: false), (
      m,
    ) {
      return date.day.toString().padLeft(m.group(0)!.length, '0');
    });

    // 星期处理 (E -> 星期日)
    format = format.replaceAllMapped(RegExp(r'E+', caseSensitive: false), (m) {
      return daysOfWeek[date.weekday % 7];
    });

    // 小时补零 (h -> 1, hh -> 01)
    format = format.replaceAllMapped(RegExp(r'(h+)', caseSensitive: false), (
      m,
    ) {
      return date.hour.toString().padLeft(m.group(0)!.length, '0');
    });

    // 分钟补零 (m -> 1, mm -> 01)
    format = format.replaceAllMapped(RegExp(r'(m+)'), (m) {
      return date.minute.toString().padLeft(m.group(0)!.length, '0');
    });

    // 秒数补零 (s -> 1, ss -> 01)
    format = format.replaceAllMapped(RegExp(r'(s+)', caseSensitive: false), (
      m,
    ) {
      return date.second.toString().padLeft(m.group(0)!.length, '0');
    });
    return format;
  }

  static int convertLocalToUtc(String dateStr) {
    final format = DateFormat('yyyy-MM-dd HH:mm:ss');
    final localDate = format.parse(dateStr);
    return localDate.toUtc().millisecondsSinceEpoch;
  }

  /// Time difference information structure

  /// Calculate detailed time difference between two timestamps
  static TimeDifference calculateTimeDifference2(
    int timestamp1,
    int timestamp2,
  ) {
    final t1 = normalizeTimestamp(timestamp1);
    final t2 = normalizeTimestamp(timestamp2);

    final start = t1 < t2 ? t1 : t2;
    final end = t1 < t2 ? t2 : t1;

    final difference = end - start; // in milliseconds

    // Calculate time components
    final secondsTotal = difference ~/ 1000;
    final minutesTotal = secondsTotal ~/ 60;
    final hoursTotal = minutesTotal ~/ 60;
    final daysTotal = hoursTotal ~/ 24;

    return TimeDifference(
      days: daysTotal.toString(),
      hours: (hoursTotal % 24).toString().padLeft(2, '0'),
      minutes: (minutesTotal % 60).toString().padLeft(2, '0'),
      seconds: (secondsTotal % 60).toString().padLeft(2, '0'),
    );
  }

  static String calculateDays(int timestamp1, int timestamp2, [int tag = 4]) {
    // 处理秒级时间戳
    timestamp1 = normalizeTimestamp(timestamp1);
    timestamp2 = normalizeTimestamp(timestamp2);

    final millisecondsDiff = (timestamp2 - timestamp1).abs();
    final daysDiff = (millisecondsDiff / day).floor();

    switch (tag) {
      case 1:
        final weeks = (daysDiff / 7).floor();
        final remainingDays = daysDiff % 7;
        return remainingDays == 0 ? '$weeks周' : '$weeks周$remainingDays天';
      case 2:
        final months = (daysDiff / 30).floor();
        final remainingDays = daysDiff % 30;
        return remainingDays == 0 ? '$months个月' : '$months个月$remainingDays天';
      case 3:
        final years = (daysDiff / 365).floor();
        final months = ((daysDiff % 365) / 30).floor();
        final remainingDays = (daysDiff % 365) % 30;
        if (months == 0) return '$years年';
        if (remainingDays == 0) return '${years}年$months个月';
        return '$years年$months个月${remainingDays.toString().padLeft(2, "0")}天';
      default:
        return daysDiff.toString();
    }
  }

  /// 获取存储权限
  static Future<bool> getPhotoPermission() async {
    try {
      // 检查平台并处理权限请求
      if (Platform.isIOS) {
        // iOS: 请求“仅添加照片”权限
        final status = await Permission.photosAddOnly.request();
        return status == PermissionStatus.granted;
      } else if (Platform.isAndroid) {
        // Android: 根据SDK版本选择权限类型
        final androidInfo = await DeviceInfoPlugin().androidInfo;
        final permission =
            androidInfo.version.sdkInt <= 32
                ? Permission.storage
                : Permission.photos;
        final status = await permission.request();
        return status == PermissionStatus.granted;
      }
      return false;
    } catch (e) {
      print('Error requesting photo permission: $e');
      return false;
    }
  }

  void checkPermission() async {
    // 请求存储权限
    final permissionState = await getPhotoPermission();
    if (permissionState) {
      // 权限被授予
    } else {
      // 权限被拒绝 打开手机上该App的权限设置页面
      openAppSettings();
    }
  }

  static bool checkImageUrlQuote(
    List<CountdownEventClass> arr,
    String imageUrl, {
    String excludeChildrenId = '',
  }) {
    if (imageUrl.isEmpty) return false;
    var eventChildrenArr = arr.expand((item) => item.eventChildren);
    return eventChildrenArr.any(
      (item) =>
          item.imgUrl.value == imageUrl &&
          item.childrenId.value != excludeChildrenId,
    );
  }

  static Future<void> delteCacheImage(
    List<CountdownEventClass> arr,
    String imagePath,
    String excludeChildrenId,
  ) async {
    if (!checkImageUrlQuote(
      arr,
      imagePath,
      excludeChildrenId: excludeChildrenId,
    )) {
      if (imagePath.isEmpty) return;
      var imageFile = File(imagePath);
      if (imageFile.existsSync()) {
        await imageFile.delete();
      }
    }
  }
}
